home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 2: Applications / Linux Cubed Series 2 - Applications.iso / utils / console / splitvt-.000 / splitvt- / splitvt-1.6.1 / utmp.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-12-05  |  4.9 KB  |  239 lines

  1.  
  2. /*  utmp.c    Shareware Copyright by Sam Lantinga    10/6/93    */
  3.  
  4. #include    <sys/types.h>
  5. #include    <sys/stat.h>
  6. #include    <fcntl.h>
  7. #include    <utmp.h>
  8. #include    <stdio.h>
  9.  
  10. #ifdef DEBUG_UTMP
  11. #undef  UTMP_FILE
  12. #define UTMP_FILE  "/tmp/utmp"
  13. #else
  14. #ifndef UTMP_FILE
  15. #define UTMP_FILE  "/etc/utmp"
  16. #endif /* UTMP_FILE */
  17. #endif /* DEBUG_UTMP */
  18.  
  19.  
  20. /* Remove us from the utmp file, saving our entry to replace later */
  21.  
  22. static struct utmp saved_utmp;
  23. static int utmp_saved=0;
  24. static char saved_tty[128];
  25.  
  26. int remove_me()
  27. {
  28.     struct utmp ut;
  29.     char *tty;
  30.     time_t now;
  31.  
  32.     if ( (! isatty(0)) || ((tty=(char *)ttyname(0)) == NULL) )
  33.         return(-1);
  34.  
  35.     /* Retrieve our utmp record */
  36.     (void) time(&now);
  37.     if ( get_utmp(tty, &ut) == 0 ) {
  38.         /* Save the utmp entry and tty pathname */
  39.         utmp_saved=1;
  40.         d_copy((char *)&ut, (char *)&saved_utmp, sizeof(ut));
  41.         strcpy(saved_tty, tty);
  42.  
  43.         /* Clean out the entry and return */
  44.         ut.ut_name[0]='\0';
  45.         ut.ut_time=now;
  46. #ifdef USER_PROCESS
  47.         ut.ut_type = DEAD_PROCESS;
  48. #endif
  49. #ifdef HAVE_UTHOST
  50.         ut.ut_host[0]='\0';
  51. #endif
  52.         return(set_utmp(tty, &ut));
  53.     }
  54.     /* Nothing to clean out, good. */
  55.     return(0);
  56. }
  57.  
  58.  
  59. int replace_me()
  60. {
  61.     if ( utmp_saved )
  62.         return(set_utmp(saved_tty, &saved_utmp));
  63.     return(0);
  64. }
  65.     
  66. int get_utmp(tty, save)
  67. char *tty;
  68. struct utmp *save;
  69. {
  70.     int fd;
  71.     char *ttyptr;
  72.     struct utmp ut;
  73.  
  74.     /* See if we can open the utmp file */
  75.     if ( (fd=open(UTMP_FILE, O_RDWR)) < 0 )
  76.         return(-1);
  77.  
  78.     /* Get the ttyxy form of the tty pathname if possible. */
  79.     if ( *tty == '/' ) {
  80.         for ( ttyptr=(tty+1); *ttyptr; ++ttyptr ) {
  81.             if ( *ttyptr == '/' )
  82.                 break;
  83.         }
  84.         if ( *ttyptr == '/' )
  85.             ++ttyptr;
  86.     } else
  87.         ttyptr=tty;
  88.  
  89.     while (read(fd,(char *) &ut, sizeof(ut)) == sizeof(ut)) {
  90.           if (strncmp(ttyptr, ut.ut_line, sizeof(ut.ut_line)) == 0) {
  91.             /* Break out; we've found our entry! */
  92.             if ( save )
  93.                 d_copy((char *)&ut, save, sizeof(ut));
  94.             close(fd);
  95.             return(0);
  96.             }
  97.       }
  98.     /* We never found an entry for our tty */
  99.     close(fd);
  100.     return(-1);
  101. }
  102.  
  103. int set_utmp(tty, save)
  104. char *tty;
  105. struct utmp *save;
  106. {
  107.     int fd, found=0;
  108.     char *ttyptr;
  109.     struct utmp ut;
  110.  
  111.     /* See if we can open the utmp file */
  112.     if ( (fd=open(UTMP_FILE, O_RDWR)) < 0 )
  113.         return(-1);
  114.  
  115.     /* Get the ttyxy form of the tty pathname if possible. */
  116.     if ( *tty == '/' ) {
  117.         for ( ttyptr=(tty+1); *ttyptr; ++ttyptr ) {
  118.             if ( *ttyptr == '/' )
  119.                 break;
  120.         }
  121.         if ( *ttyptr == '/' )
  122.             ++ttyptr;
  123.     } else
  124.         ttyptr=tty;
  125.  
  126.     while (read(fd,(char *) &ut, sizeof(ut)) == sizeof(ut)) {
  127.           if (strncmp(ttyptr, ut.ut_line, sizeof(ut.ut_line)) == 0) {
  128.             found=1;
  129.             lseek(fd, -(long)sizeof(struct utmp), 1);
  130.                  break;
  131.             }
  132.       }
  133.  
  134.     /* Add a new entry to the utmp file if we can't find our entry */
  135.     if ( ! found )
  136.       { /* Reopen to avoid a race with other end-of-utmp entries. */
  137.            (void) close(fd);
  138.            if ( (fd=open(UTMP_FILE, (O_RDWR|O_APPEND))) < 0 )
  139.                  return -1;
  140.       }
  141.  
  142.      if (write(fd, (char *)save, sizeof(*save)) != sizeof(*save)) {
  143.            (void) close(fd);
  144.            return -1;
  145.       }
  146.      return(close(fd));
  147. }
  148.  
  149.     
  150. /* Set up a utmp entry and tty for a user */
  151.  
  152. int addutmp(user, uid, tty)
  153. char *user;        /* The user to add to the utmp file */
  154. int uid;        /* The uid corresponding to user */
  155. char *tty;        /* /dev/ttyxx */
  156. {
  157.     struct stat sb;
  158.     struct utmp ut;
  159.     char *ttyptr;
  160.  
  161.     /* Retrieve any existing utmp entry */
  162.     d_zero((char *)&ut, sizeof(ut));
  163.     (void) get_utmp(tty, &ut);
  164.  
  165.     /* Get the ttyxy form of the tty pathname if possible. */
  166.     if ( *tty == '/' ) {
  167.         for ( ttyptr=(tty+1); *ttyptr; ++ttyptr ) {
  168.             if ( *ttyptr == '/' )
  169.                 break;
  170.         }
  171.         if ( *ttyptr == '/' )
  172.             ++ttyptr;
  173.     } else
  174.         ttyptr=tty;
  175.  
  176.     /* Customize the utmp entry */
  177.     strncpy(ut.ut_name, user, sizeof(ut.ut_name));
  178.     strncpy(ut.ut_line, ttyptr, sizeof(ut.ut_line));
  179. #ifdef USER_PROCESS
  180.     ut.ut_type=USER_PROCESS;
  181.     ut.ut_pid=getpid();
  182. #endif
  183. #if defined(HAVE_UTHOST)
  184.     /* remove_me() should be called before this function */
  185.     if ( utmp_saved )
  186.         strncpy(ut.ut_host, saved_utmp.ut_host, sizeof(ut.ut_host));
  187. #endif
  188.     (void) time(&ut.ut_time);
  189.  
  190. #if !defined(SOLARIS) && !defined(IRIX)
  191.     /* Solaris and Irix machines do this automatically */
  192.     /* Change the ownership and mode of the tty */
  193.     if ( stat(tty, &sb) == 0 ) {
  194.         (void) chmod(tty, 0620);  /* crw--w---- */
  195.         (void) chown(tty, uid, sb.st_gid);
  196.     }
  197. #endif
  198.     return(set_utmp(tty, &ut));
  199. }
  200.     
  201.  
  202. /* End a utmp entry and tty for a user and a tty */
  203.  
  204. int delutmp(user, tty)
  205. char *user;
  206. char *tty;        /* /dev/ttyxx */
  207. {
  208.     struct stat sb;
  209.     struct utmp ut;
  210.     int retval=0;
  211.  
  212.     /* Retrieve any existing utmp entry */
  213.     d_zero((char *)&ut, sizeof(ut));
  214.     if ( get_utmp(tty, &ut) == 0 ) {
  215.         /* Clear the utmp entry */
  216.         ut.ut_name[0]='\0';
  217. #ifdef USER_PROCESS
  218.         ut.ut_type=DEAD_PROCESS;
  219. #endif
  220. #if defined(HAVE_UTHOST)
  221.         ut.ut_host[0]='\0';
  222. #endif
  223.         (void) time(&ut.ut_time);
  224.         retval=set_utmp(tty, &ut);
  225.     }
  226.  
  227. #if !defined(SOLARIS) && !defined(IRIX)
  228.     /* Solaris and Irix machines do this automatically */
  229.     /* Reset the owner and mode of the tty */
  230.     if ( stat(tty, &sb) == 0 ) {
  231.         (void) chmod(tty, 0666);    /* crw-rw-rw- */
  232.         (void) chown(tty, 0, sb.st_gid);
  233.     }
  234. #endif
  235.     return(retval);
  236. }
  237.  
  238.  
  239.